package com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ExceptionCast;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.common.util.ApiModelUtil;
import com.xyht.sca_s.student_manage_system.common.util.CacheUtil;
import com.xyht.sca_s.student_manage_system.common.util.TimeUtil;
import com.xyht.sca_s.student_manage_system.modules.asset.entity.SmsAssetCategoryManagement;
import com.xyht.sca_s.student_manage_system.modules.asset.entity.SmsAssetFixedStorage;
import com.xyht.sca_s.student_manage_system.modules.asset.entity.SmsAssetProcess;
import com.xyht.sca_s.student_manage_system.modules.asset.entity.SmsAssetProcessDetail;
import com.xyht.sca_s.student_manage_system.modules.asset.mapper.SmsAssetCategoryManagementMapper;
import com.xyht.sca_s.student_manage_system.modules.asset.mapper.SmsAssetFixedStorageMapper;
import com.xyht.sca_s.student_manage_system.modules.asset.mapper.SmsAssetProcessDetailMapper;
import com.xyht.sca_s.student_manage_system.modules.asset.mapper.SmsAssetProcessMapper;
import com.xyht.sca_s.student_manage_system.modules.assetFixedBorrow.entity.SmsAssetMyAssets;
import com.xyht.sca_s.student_manage_system.modules.assetFixedBorrow.entity.dto.SmsAssetMyAssetsDTO;
import com.xyht.sca_s.student_manage_system.modules.assetFixedBorrow.mapper.SmsAssetFixedBorrowApplyMapper;
import com.xyht.sca_s.student_manage_system.modules.assetFixedBorrow.mapper.SmsAssetMyAssetsMapper;
import com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.entity.SmsAssetFixedReturnApply;
import com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.entity.SmsAssetFixedReturnApplyGoodsDetail;
import com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.entity.SmsAssetFixedReturnApplyProcessDetail;
import com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.entity.dto.SmsAssetFixedReturnApplyDTO;
import com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.entity.dto.SmsAssetFixedReturnApplyGoodsDTO;
import com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.entity.dto.SmsAssetFixedReturnApplyMPJDTO;
import com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.entity.dto.SmsAssetFixedReturnApplyProcessDetailDTO;
import com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.entity.vo.SmsAssetFixedReturnApplyAllowVO;
import com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.entity.vo.SmsAssetFixedReturnApplyExportVO;
import com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.entity.vo.SmsAssetFixedReturnApplyProcessDetailVO;
import com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.entity.vo.SmsAssetFixedReturnApplyVO;
import com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.mapper.*;
import com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.service.SmsAssetFixedReturnApplyService;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.AppTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.RangeTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.TipsTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.util.NewTipsUtil;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import com.xyht.sca_s.student_manage_system.modules.user.entity.resp.SmsSearchUserResp;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.asset.constant.AssetBooleanConstant.ASSET_BOOLEAN_FALSE;
import static com.xyht.sca_s.student_manage_system.modules.asset.constant.AssetBooleanConstant.ASSET_BOOLEAN_TRUE;
import static com.xyht.sca_s.student_manage_system.modules.assetFixedBorrow.constant.MyAssetStatusConstant.MY_ASSET_STATUS_BORROW;
import static com.xyht.sca_s.student_manage_system.modules.assetFixedBorrow.constant.MyAssetStatusConstant.MY_ASSET_STATUS_RETURN;
import static com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.constant.AssetAllowStatusConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.constant.AssetApplyTypeConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.constant.AssetObjectTypeConstant.ASSET_RETURN_OBJECT_TYPE_PERSON;
import static com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.constant.AssetObjectTypeConstant.ASSET_RETURN_OBJECT_TYPE_ROLE;
import static com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.constant.AssetProcessTypeConstant.ASSET_PROCESS_TYPE_FIXED_RETURN_STORAGE;
import static com.xyht.sca_s.student_manage_system.modules.assetFixedReturn.constant.AssetStatusConstant.ASSET_STATUS_IN_STORAGE;
import static com.xyht.sca_s.student_manage_system.modules.examinePaymentEquipment.constant.isExportProcessConstant.EXPORT_PROCESS_TRUE;
import static com.xyht.sca_s.student_manage_system.modules.examinePaymentEquipment.constant.paymentExamineStatusConstant.EXAMINE_STATUS_DENY;
import static com.xyht.sca_s.student_manage_system.modules.examinePaymentEquipment.constant.paymentExamineStatusConstant.EXAMINE_STATUS_PASS;
import static com.xyht.sca_s.student_manage_system.modules.student.constant.StudentInfoCommonConstant.PER_SHEET_NUM;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2023-06-01
 */
@Service
public class SmsAssetFixedReturnApplyServiceImpl extends ServiceImpl<SmsAssetFixedReturnApplyMapper, SmsAssetFixedReturnApply> implements SmsAssetFixedReturnApplyService {
    @Autowired
    SmsAssetFixedReturnApplyMapper smsAssetFixedReturnApplyMapper;
    @Autowired
    SmsAssetProcessDetailMapper smsAssetProcessDetailMapper;
    @Autowired
    SmsAssetCategoryManagementMapper smsAssetCategoryManagementMapper;
    @Autowired
    SmsAssetFixedReturnApplyGoodsMapper smsAssetFixedReturnApplyGoodsMapper;
    @Autowired
    SmsAssetProcessMapper smsAssetProcessMapper;
    @Autowired
    SmsAssetFixedReturnApplyProcessDetailMapper smsAssetFixedReturnApplyProcessDetailMapper;
    @Autowired
    NewTipsUtil newTipsUtil;
    @Autowired
    CacheUtil cacheUtil;
    @Autowired
    SmsAssetFixedReturnApplyProcessDetailMPJMapper smsAssetFixedReturnApplyProcessDetailMPJMapper;
    @Autowired
    SmsAssetFixedReturnApplyGoodsDetailMapper smsAssetFixedReturnApplyGoodsDetailMapper;
    @Autowired
    SmsAssetFixedStorageMapper smsAssetFixedStorageMapper;
    @Autowired
    SmsAssetFixedBorrowApplyMapper smsAssetFixedBorrowApplyMapper;
    @Autowired
    SmsAssetMyAssetsMapper smsAssetMyAssetsMapper;
    @Autowired
    ApiModelUtil apiModelUtil;


    @Transactional
    @Override
    public ResponseResult assetFixedReturnAdd(SmsAssetFixedReturnApplyVO applyVO, String user_id) {
        if (isNullOrEmpty(applyVO.getApplyName()) || isNullOrEmpty(applyVO.getApplyDepartment()) || isNullOrEmpty(applyVO.getApplyPerson())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

//        if (applyVO.getGoodsList().size() < 1) {
//            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
//        }
        if (isNullOrEmpty(applyVO.getAssetIdList()) || applyVO.getAssetIdList().size() < 1) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsAssetProcess originProcess1 = smsAssetProcessMapper.selectOne(new QueryWrapper<SmsAssetProcess>()
                .lambda()
                .eq(SmsAssetProcess::getProcessType, ASSET_PROCESS_TYPE_FIXED_RETURN_STORAGE));
        List<SmsAssetProcessDetail> fillProcessList =
                smsAssetProcessDetailMapper.selectList(new QueryWrapper<SmsAssetProcessDetail>()
                        .lambda()
                        .eq(SmsAssetProcessDetail::getProcessId, originProcess1.getId())
                        .eq(SmsAssetProcessDetail::getProcessDetailIsApplicantEdit, true)
                        .eq(SmsAssetProcessDetail::getProcessDetailIsUse, true)
                        .orderByAsc(SmsAssetProcessDetail::getProcessDetailSort));
        if (fillProcessList != null && fillProcessList.size() > 0) {
            if (applyVO.getProcessList() == null || applyVO.getProcessList().size() < 1) {
                return CommonResult.failed(CommonCodeEnum.ASSET_RETURN_ALLOW_USER_NOT_SETTING);
            }
            //判断申请人是否将全部需要编辑流程填写
            List<SmsAssetProcessDetail> filterList = fillProcessList
                    .stream()
                    .filter(process -> {
                                List<SmsAssetFixedReturnApplyProcessDetailVO> result = applyVO.getProcessList()
                                        .stream()
                                        .filter(fillProcess -> fillProcess.getProcessDetailId().equals(process.getId()))
                                        .collect(Collectors.toList());
                                //匹配的去除  未匹配的留下
                                if (result.size() > 0) {
                                    return false;
                                } else {
                                    return true;
                                }
                            }
                    )
                    .collect(Collectors.toList());
            if (filterList.size() > 0) {
                return CommonResult.failed(CommonCodeEnum.ASSET_RETURN_ALLOW_PROCESS_NOT_FILL);
            }
        }
        //创建申请表
        SmsAssetFixedReturnApply smsAssetFixedReturnApply = new SmsAssetFixedReturnApply();
        BeanUtils.copyProperties(applyVO, smsAssetFixedReturnApply);
        smsAssetFixedReturnApply.setApplyUserId(user_id);
        smsAssetFixedReturnApply.setAllowStatus(ASSET_RETURN_ALLOW_STATUS_WAIT_ALLOW);
        smsAssetFixedReturnApplyMapper.insert(smsAssetFixedReturnApply);
        if (isNullOrEmpty(smsAssetFixedReturnApply.getId())) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.FAIL));
        }
        String apply_id = smsAssetFixedReturnApply.getId();

        //创建归还申请物品记录
//        for (SmsAssetFixedReturnApplyGoodsVO goodsVO : applyVO.getGoodsList()) {
//            if (isNullOrEmpty(goodsVO.getAssetName()) || isNullOrEmpty(goodsVO.getAssetNum())
//                    || isNullOrEmpty(goodsVO.getAssetCategory()) || isNullOrEmpty(goodsVO.getAssetModel())) {
//                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
//            }
//            SmsAssetCategoryManagement smsAssetCategoryManagement =
//                    smsAssetCategoryManagementMapper.selectById(goodsVO.getAssetCategory());
//            if (isNullOrEmpty(smsAssetCategoryManagement.getId()) || smsAssetCategoryManagement == null) {
//                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.ASSET_RETURN_CATEGORY_NOT_EXIST));
//            }
//            //判断是否为根类别
//            if (smsAssetCategoryManagement.getId().length() < 3) {
//                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.ASSET_RETURN_CATEGORY_CAN_NOT_USE_ROOT));
//            }
//
//            //判断数量
//            if (goodsVO.getAssetNum().equals(0)) {
//                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.ASSET_RETURN_STORAGE_NUM_ERR));
//            }
//            SmsAssetFixedReturnApplyGoods smsAssetFixedreturnApplyGoods = new SmsAssetFixedReturnApplyGoods();
//            BeanUtils.copyProperties(goodsVO, smsAssetFixedreturnApplyGoods);
//            smsAssetFixedreturnApplyGoods.setApplyId(apply_id);
//            smsAssetFixedReturnApplyGoodsMapper.insert(smsAssetFixedreturnApplyGoods);
//        }
        //创建归还申请物品记录
        //判断物品是否被借用
        List<String> assetIdList = applyVO.getAssetIdList().stream().distinct().collect(Collectors.toList());
        for (String myAssetId : assetIdList) {
            SmsAssetMyAssets myAssets = smsAssetMyAssetsMapper.selectById(myAssetId);
            if (myAssets == null || myAssets.getMyAssetStatus() == MY_ASSET_STATUS_RETURN) {
                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.ASSET_RETURN_STORAGE_NOT_EXIST));
            }

            SmsAssetFixedStorage fixedStorage = smsAssetFixedStorageMapper.selectById(myAssets.getAssetId());
            if (fixedStorage == null ){
                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.ASSET_RETURN_STORAGE_NOT_EXIST));
            }

            SmsAssetFixedReturnApplyGoodsDetail goodsDetail = new SmsAssetFixedReturnApplyGoodsDetail();
            goodsDetail.setApplyId(apply_id);
            goodsDetail.setAssetId(myAssets.getAssetId());
            goodsDetail.setMyAssetId(myAssetId);
            smsAssetFixedReturnApplyGoodsDetailMapper.insert(goodsDetail);
        }


        //创建审批流程
        //主流程

        //流程节点
        List<SmsAssetProcessDetail> originProcessDetailList =
                smsAssetProcessDetailMapper.selectList(new QueryWrapper<SmsAssetProcessDetail>()
                        .lambda()
                        .eq(SmsAssetProcessDetail::getProcessDetailIsUse, ASSET_BOOLEAN_TRUE)
                        .eq(SmsAssetProcessDetail::getProcessId, originProcess1.getId())
                        .orderByAsc(SmsAssetProcessDetail::getProcessDetailSort));
        if (originProcessDetailList == null || originProcessDetailList.size() < 1) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.ASSET_RETURN_PROCESS_NOT_SETTING));
        }
        int sort = 1;
        for (SmsAssetProcessDetail process : originProcessDetailList) {
            //判断管理员是否配置初始流程
            if (process.getProcessDetailIsApplicantEdit().equals(ASSET_BOOLEAN_FALSE)) {
                if (isNullOrEmpty(process.getProcessDetailObjectId()) || isNullOrEmpty(process.getProcessDetailObjectType())) {
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.ASSET_RETURN_PROCESS_NOT_SETTING));
                }
            }

            SmsAssetFixedReturnApplyProcessDetail addDetail =
                    new SmsAssetFixedReturnApplyProcessDetail();

            addDetail.setApplyId(apply_id);
            addDetail.setProcessDetailId(process.getId());
            addDetail.setProcessDetailIsSign(process.getProcessDetailIsSign());
            addDetail.setProcessDetailIsStamp(process.getProcessDetailIsStamp());
            addDetail.setProcessDetailName(process.getProcessDetailName());
            addDetail.setProcessDetailStatus(ASSET_RETURN_ALLOW_STATUS_WAIT_ALLOW);

            addDetail.setProcessDetailSort(sort++);

            //申请人可编辑流程
            if (process.getProcessDetailIsApplicantEdit().equals(ASSET_BOOLEAN_TRUE)) {
                List<SmsAssetFixedReturnApplyProcessDetailVO> filterList = applyVO.getProcessList()
                        .stream()
                        .filter(fillProcess -> fillProcess.getProcessDetailId().equals(process.getId()))
                        .collect(Collectors.toList());
                if (filterList.size() < 1) {
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.ASSET_RETURN_ALLOW_PROCESS_NOT_FILL));
                }
                SmsAssetFixedReturnApplyProcessDetailVO fillProcessReq = filterList.get(0);

                if (isNullOrEmpty(fillProcessReq.getProcessDetailObjectId())) {
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
                }
                addDetail.setProcessDetailObjectId(fillProcessReq.getProcessDetailObjectId());
                addDetail.setProcessDetailObjectType(fillProcessReq.getProcessDetailObjectType());
            } else {
                addDetail.setProcessDetailObjectId(process.getProcessDetailObjectId());
                addDetail.setProcessDetailObjectType(process.getProcessDetailObjectType());
            }
            smsAssetFixedReturnApplyProcessDetailMapper.insert(addDetail);
        }
        //消息通知
        //消息通知
        //通知流程第一个节点
        SmsAssetFixedReturnApplyProcessDetail firstDetail =
                smsAssetFixedReturnApplyProcessDetailMapper.selectOne(new QueryWrapper<SmsAssetFixedReturnApplyProcessDetail>()
                        .lambda()
                        .eq(SmsAssetFixedReturnApplyProcessDetail::getApplyId, apply_id)
                        .eq(SmsAssetFixedReturnApplyProcessDetail::getProcessDetailSort, 1)
                        .orderByAsc(SmsAssetFixedReturnApplyProcessDetail::getProcessDetailSort));
        RangeTypeEnum rangeTypeEnum;
        if (firstDetail.getProcessDetailObjectType() == ASSET_RETURN_OBJECT_TYPE_PERSON) {
            rangeTypeEnum = RangeTypeEnum.RANGE_TYPE_ENUM_PERSON;
        } else {
            rangeTypeEnum = RangeTypeEnum.RANGE_TYPE_ENUM_ROLE;
        }
        List<String> rangeList = new ArrayList<>();
        rangeList.add(firstDetail.getProcessDetailObjectId());

        newTipsUtil.addNewTips(TipsTypeEnum.TIPS_TYPE_ENUM_ALLOW,
                user_id,
                rangeTypeEnum,
                rangeList,
                AppTypeEnum.APP_TYPE_ENUM_ASSET,
                apply_id,
                firstDetail.getId());
        return CommonResult.success();
    }

    @Transactional
    @Override
    public ResponseResult cancelAssetFixedReturn(SmsAssetFixedReturnApplyVO cancelVO, String user_id) {
        if (isNullOrEmpty(cancelVO.getApplyId())) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }
        SmsAssetFixedReturnApply assetReturnApply =
                smsAssetFixedReturnApplyMapper.selectOne(new QueryWrapper<SmsAssetFixedReturnApply>()
                        .lambda()
                        .eq(SmsAssetFixedReturnApply::getApplyUserId, user_id)
                        .eq(SmsAssetFixedReturnApply::getId, cancelVO.getApplyId()));
        if (assetReturnApply == null) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.ASSET_RETURN_APPLY_NOT_EXIST));
        }
        if (assetReturnApply.getAllowStatus() != ASSET_RETURN_ALLOW_STATUS_WAIT_ALLOW) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.ASSET_RETURN_CANCEL_FAIL_ALLOWED));
        }
        //判断是否审批中
        List<SmsAssetFixedReturnApplyProcessDetail> processDetailList =
                smsAssetFixedReturnApplyProcessDetailMapper.selectList(new QueryWrapper<SmsAssetFixedReturnApplyProcessDetail>()
                        .lambda()
                        .eq(SmsAssetFixedReturnApplyProcessDetail::getApplyId, cancelVO.getApplyId())
                        .eq(SmsAssetFixedReturnApplyProcessDetail::getProcessDetailStatus, ASSET_RETURN_ALLOW_STATUS_PASS));
        if (processDetailList.size() > 0 && processDetailList != null) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.ASSET_RETURN_CANCEL_FAIL_ALLOWED));
        }

        //撤销申请
        SmsAssetFixedReturnApply cancelApply = new SmsAssetFixedReturnApply();
        cancelApply.setId(cancelVO.getApplyId());
        cancelApply.setAllowStatus(ASSET_RETURN_ALLOW_STATUS_CANCEL);
        cancelApply.setEndTime(new Date());
        smsAssetFixedReturnApplyMapper.updateById(cancelApply);
        //修改节点状态
        SmsAssetFixedReturnApplyProcessDetail cancelProcessDetail = new SmsAssetFixedReturnApplyProcessDetail();
        cancelProcessDetail.setProcessDetailStatus(ASSET_RETURN_ALLOW_STATUS_CANCEL);
        smsAssetFixedReturnApplyProcessDetailMapper.update(cancelProcessDetail, new QueryWrapper<SmsAssetFixedReturnApplyProcessDetail>()
                .lambda()
                .eq(SmsAssetFixedReturnApplyProcessDetail::getApplyId, cancelVO.getApplyId()));
        //消息通知
        newTipsUtil.cancelFinishTips(cancelVO.getApplyId());
        return CommonResult.success();
    }

    @Transactional
    @Override
    public ResponseResult getAssetFixedReturnList(Integer apply_type, Integer pageSize, Integer pageNum, String user_id) {
        if (isNullOrEmpty(apply_type)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        List<SmsAssetFixedReturnApplyDTO> respList = new ArrayList<>();
        int total = 0;
        //查看已发起
        if (apply_type == ASSET_RETURN_APPLY_TYPE_APPLY) {
            Page<SmsAssetFixedReturnApply> page = new Page<>(pageNum, pageSize);
            QueryWrapper<SmsAssetFixedReturnApply> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SmsAssetFixedReturnApply::getApplyUserId, user_id)
                    .orderByDesc(SmsAssetFixedReturnApply::getCreateTime);
            smsAssetFixedReturnApplyMapper.selectPage(page, queryWrapper);
            respList = page.getRecords()
                    .stream()
                    .map(apply -> {
                        SmsAssetFixedReturnApplyDTO borrowApplyDTO =
                                new SmsAssetFixedReturnApplyDTO();
                        BeanUtils.copyProperties(apply, borrowApplyDTO);
                        borrowApplyDTO.setApplyId(apply.getId());
                        SmsUser smsUser = cacheUtil.getUserInfo(apply.getApplyUserId());
                        SmsSearchUserResp userResp = new SmsSearchUserResp();
                        if (!isNullOrEmpty(smsUser)) {
                            BeanUtils.copyProperties(smsUser, userResp);
                        }
                        borrowApplyDTO.setApplyUserInfo(userResp);
                        return borrowApplyDTO;
                    })
                    .collect(Collectors.toList());
        }
        //查看已办类型
        else if (apply_type == ASSET_RETURN_APPLY_TYPE_ALLOWED) {
            Page<SmsAssetFixedReturnApplyMPJDTO> page = new Page<>(pageNum, pageSize);
            MPJLambdaWrapper<SmsAssetFixedReturnApplyProcessDetail> mpjLambdaWrapper = new MPJLambdaWrapper<>();
            mpjLambdaWrapper.selectAll(SmsAssetFixedReturnApplyProcessDetail.class)
                    .selectAll(SmsAssetFixedReturnApply.class)
                    .selectAs(SmsAssetFixedReturnApply::getCreateTime, "applyCreateTime")
                    .selectAs(SmsAssetFixedReturnApplyProcessDetail::getId, "detailId")
                    .leftJoin(SmsAssetFixedReturnApply.class, SmsAssetFixedReturnApply::getId, SmsAssetFixedReturnApplyProcessDetail::getApplyId)
                    .eq(SmsAssetFixedReturnApplyProcessDetail::getAllowUserId, user_id)
                    //.orderByDesc(SmsAssetFixedReturnApply::getCreateTime)
                    .orderByDesc(SmsAssetFixedReturnApplyProcessDetail::getEndTime);
            smsAssetFixedReturnApplyProcessDetailMPJMapper.selectJoinPage(page, SmsAssetFixedReturnApplyMPJDTO.class, mpjLambdaWrapper);
            respList = page.getRecords()
                    .stream()
                    .map(smsMPJResp -> {
                        SmsAssetFixedReturnApplyDTO applyResp = new SmsAssetFixedReturnApplyDTO();
                        BeanUtils.copyProperties(smsMPJResp, applyResp);
                        applyResp.setCreateTime(smsMPJResp.getApplyCreateTime());
                        applyResp.setEndTime(smsMPJResp.getEndTime());
                        SmsUser smsUser = cacheUtil.getUserInfo(smsMPJResp.getAllowUserId());
                        SmsSearchUserResp allowUserResp = new SmsSearchUserResp();
                        if (!isNullOrEmpty(smsUser)) {
                            BeanUtils.copyProperties(smsUser, allowUserResp);
                        }
                        applyResp.setApplyUserInfo(allowUserResp);
                        return applyResp;
                    }).collect(Collectors.toList());
            total = (int) page.getTotal();
        } else if (apply_type == ASSET_RETURN_APPLY_TYPE_ALLOW_WAIT_ME) {
            List<String> roleList = cacheUtil.getRoleList(user_id);
            //获取所有待审批申请流程节点
            List<SmsAssetFixedReturnApplyProcessDetail> allDetailList =
                    smsAssetFixedReturnApplyProcessDetailMapper.selectList(new QueryWrapper<SmsAssetFixedReturnApplyProcessDetail>()
                            .lambda()
                            .eq(SmsAssetFixedReturnApplyProcessDetail::getProcessDetailStatus, ASSET_RETURN_ALLOW_STATUS_WAIT_ALLOW));

            List<SmsAssetFixedReturnApplyProcessDetail> filterDetailList = allDetailList.stream()
                    .filter(detail -> {
                        if (detail.getProcessDetailObjectType() == ASSET_RETURN_OBJECT_TYPE_PERSON) {
                            if (!detail.getProcessDetailObjectId().equals(user_id)) {
                                return false;
                            }
                        } else {
                            List<String> filterRoleList = roleList.stream().filter(role -> role.equals(detail.getProcessDetailObjectId())).collect(Collectors.toList());
                            if (filterRoleList.size() < 1) {
                                return false;
                            }
                        }

                        if (detail.getProcessDetailSort().equals(1)) {
                            return true;
                        }
                        //判断上一个流程节点是否完成
                        SmsAssetFixedReturnApplyProcessDetail preDetail =
                                smsAssetFixedReturnApplyProcessDetailMapper.selectOne(new QueryWrapper<SmsAssetFixedReturnApplyProcessDetail>()
                                        .lambda()
                                        .eq(SmsAssetFixedReturnApplyProcessDetail::getApplyId, detail.getApplyId())
                                        .eq(SmsAssetFixedReturnApplyProcessDetail::getProcessDetailSort, detail.getProcessDetailSort() - 1)
                                        .eq(SmsAssetFixedReturnApplyProcessDetail::getProcessDetailStatus, ASSET_RETURN_ALLOW_STATUS_PASS));
                        if (preDetail == null || isNullOrEmpty(preDetail.getId())) {
                            return false;
                        }
                        return true;
                    })
                    .collect(Collectors.toList());
            if (filterDetailList.size() > 0) {
                List<String> detailIDList = filterDetailList.stream().map(SmsAssetFixedReturnApplyProcessDetail::getId).collect(Collectors.toList());

                Page<SmsAssetFixedReturnApplyMPJDTO> page = new Page<>(pageNum, pageSize);
                MPJLambdaWrapper<SmsAssetFixedReturnApplyProcessDetail> mpjLambdaWrapper = new MPJLambdaWrapper<>();
                mpjLambdaWrapper.selectAll(SmsAssetFixedReturnApplyProcessDetail.class)
                        .selectAll(SmsAssetFixedReturnApply.class)
                        .selectAs(SmsAssetFixedReturnApply::getCreateTime, "applyCreateTime")
                        .selectAs(SmsAssetFixedReturnApplyProcessDetail::getId, "detailId")
                        .leftJoin(SmsAssetFixedReturnApply.class, SmsAssetFixedReturnApply::getId, SmsAssetFixedReturnApplyProcessDetail::getApplyId)
                        .in(SmsAssetFixedReturnApplyProcessDetail::getId, detailIDList)
                        .orderByDesc(SmsAssetFixedReturnApply::getCreateTime)
                        .orderByDesc(SmsAssetFixedReturnApplyProcessDetail::getCreateTime)
                ;
                smsAssetFixedReturnApplyProcessDetailMPJMapper.selectJoinPage(page, SmsAssetFixedReturnApplyMPJDTO.class, mpjLambdaWrapper);

                respList = page.getRecords()
                        .stream()
                        .map(smsApplyMPJResp -> {
                            SmsAssetFixedReturnApplyDTO applyResp = new SmsAssetFixedReturnApplyDTO();
                            BeanUtils.copyProperties(smsApplyMPJResp, applyResp);
                            applyResp.setCreateTime(smsApplyMPJResp.getApplyCreateTime());

                            SmsUser applyUser = cacheUtil.getUserInfo(smsApplyMPJResp.getApplyUserId());
                            SmsSearchUserResp smsExamineUserResp = new SmsSearchUserResp();
                            if (applyUser != null) {
                                BeanUtils.copyProperties(applyUser, smsExamineUserResp);
                            }
                            applyResp.setApplyUserInfo(smsExamineUserResp);

                            return applyResp;
                        })
                        .collect(Collectors.toList());
                total = (int) page.getTotal();
            }
        }

        return CommonResult.success(respList, total);
    }

    @Transactional
    @Override
    public ResponseResult getAssetFixedReturnDetail(String apply_id, String user_id) {
        if (isNullOrEmpty(apply_id)) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }
        SmsAssetFixedReturnApply assetApply = smsAssetFixedReturnApplyMapper.selectById(apply_id);
        if (assetApply == null || isNullOrEmpty(assetApply.getId())) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.ASSET_RETURN_APPLY_NOT_EXIST));
        }
        SmsAssetFixedReturnApplyDTO applyDTO = new SmsAssetFixedReturnApplyDTO();
        BeanUtils.copyProperties(assetApply, applyDTO);
        applyDTO.setApplyId(assetApply.getId());
        SmsUser smsUser = cacheUtil.getUserInfo(applyDTO.getApplyUserId());
        SmsSearchUserResp smsUserResp = new SmsSearchUserResp();
        if (smsUser != null) {
            BeanUtils.copyProperties(smsUser, smsUserResp);
        }
        applyDTO.setApplyUserInfo(smsUserResp);

        //封装流程节点
        List<SmsAssetFixedReturnApplyProcessDetailDTO> detailList =
                smsAssetFixedReturnApplyProcessDetailMapper.selectList(new QueryWrapper<SmsAssetFixedReturnApplyProcessDetail>()
                                .lambda()
                                .eq(SmsAssetFixedReturnApplyProcessDetail::getApplyId, apply_id)
                                .orderByAsc(SmsAssetFixedReturnApplyProcessDetail::getProcessDetailSort))
                        .stream()
                        .map(detail -> {
                            SmsAssetFixedReturnApplyProcessDetailDTO detailDTO = new SmsAssetFixedReturnApplyProcessDetailDTO();
                            BeanUtils.copyProperties(detail, detailDTO);
                            if (!isNullOrEmpty(detailDTO.getAllowUserId())) {
                                SmsUser userInfo = cacheUtil.getUserInfo(detailDTO.getAllowUserId());
                                SmsSearchUserResp smsSearchUserResp = new SmsSearchUserResp();
                                if (userInfo != null) {
                                    BeanUtils.copyProperties(userInfo, smsSearchUserResp);
                                }
                                detailDTO.setAllowUserInfo(smsSearchUserResp);
                            }
                            return detailDTO;
                        })
                        .collect(Collectors.toList());
        applyDTO.setProcessList(detailList);
        //封装物品信息
        List<SmsAssetFixedReturnApplyGoodsDTO> goodsList =
                smsAssetFixedReturnApplyGoodsDetailMapper.selectList(new QueryWrapper<SmsAssetFixedReturnApplyGoodsDetail>()
                                .lambda()
                                .eq(SmsAssetFixedReturnApplyGoodsDetail::getApplyId, apply_id))
                        .stream()
                        .map(goods -> {
                            SmsAssetFixedReturnApplyGoodsDTO goodsDTO = new SmsAssetFixedReturnApplyGoodsDTO();
                            SmsAssetFixedStorage fixedStorage = smsAssetFixedStorageMapper.getFixedStorageByID(goods.getAssetId());
                            if (fixedStorage != null){
                                BeanUtils.copyProperties(fixedStorage,goodsDTO);
                            }
//                            SmsAssetFixedReturnApplyGoodsDTO goodsDTO = new SmsAssetFixedReturnApplyGoodsDTO();
//                            BeanUtils.copyProperties(goods, goodsDTO);
//
//                            List<String> assetPreIdList = smsAssetFixedReturnApplyGoodsDetailMapper.selectList(new QueryWrapper<SmsAssetFixedReturnApplyGoodsDetail>()
//                                            .lambda()
//                                            .eq(SmsAssetFixedReturnApplyGoodsDetail::getAssetGoodsId, goods.getId()))
//                                    .stream()
//                                    .map(SmsAssetFixedReturnApplyGoodsDetail::getAssetId)
//                                    .collect(Collectors.toList());
//
                            SmsAssetCategoryManagement categoryManagement = smsAssetCategoryManagementMapper.selectById(fixedStorage.getAssetCategory());
                            if (categoryManagement != null) {
                                goodsDTO.setAssetCategoryName(categoryManagement.getCategoryName());
                            }
//                            SmsAssetCategoryManagement categoryManagement = smsAssetCategoryManagementMapper.selectById(goods.getAssetCategory());
//                            if (categoryManagement != null) {
//                                goodsDTO.setAssetCategoryName(categoryManagement.getCategoryName());
//                            }
//
//                            goodsDTO.setAssetAssetIdList(assetPreIdList);
                            return goodsDTO;
                        })
                        .collect(Collectors.toList());
        applyDTO.setGoodsList(goodsList);
        return CommonResult.success(applyDTO);
    }

    @Transactional
    @Override
    public ResponseResult allowAssetFixedReturn(SmsAssetFixedReturnApplyAllowVO allowVO, String user_id) {
        if (isNullOrEmpty(allowVO.getApplyId()) || isNullOrEmpty(allowVO.getDetailId())
                || isNullOrEmpty(allowVO.getProcessDetailStatus())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        if (allowVO.getProcessDetailStatus() != ASSET_RETURN_ALLOW_STATUS_PASS
                && allowVO.getProcessDetailStatus() != ASSET_RETURN_ALLOW_STATUS_DENY) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsAssetFixedReturnApply returnStorageApply = smsAssetFixedReturnApplyMapper.selectById(allowVO.getApplyId());
        if (isNullOrEmpty(returnStorageApply)) {
            return CommonResult.failed(CommonCodeEnum.ASSET_RETURN_APPLY_NOT_EXIST);
        }
        SmsAssetFixedReturnApplyProcessDetail processDetail =
                smsAssetFixedReturnApplyProcessDetailMapper.selectOne(new QueryWrapper<SmsAssetFixedReturnApplyProcessDetail>()
                        .lambda()
                        .eq(SmsAssetFixedReturnApplyProcessDetail::getApplyId, allowVO.getApplyId())
                        .eq(SmsAssetFixedReturnApplyProcessDetail::getId, allowVO.getDetailId())
                        .eq(SmsAssetFixedReturnApplyProcessDetail::getProcessDetailStatus, ASSET_RETURN_ALLOW_STATUS_WAIT_ALLOW));
        if (isNullOrEmpty(processDetail.getId()) || processDetail == null) {
            return CommonResult.failed(CommonCodeEnum.ASSET_ALLOW_FAIL);
        }
        SmsAssetFixedReturnApplyProcessDetail allowDetail = new SmsAssetFixedReturnApplyProcessDetail();
//        QueryWrapper<SmsAssetFixedReturnApply> queryWrapper = new QueryWrapper<>();
//        queryWrapper.lambda()
//                    .eq(SmsAssetFixedReturnApply::getApplyUserId,)
        allowDetail.setId(allowVO.getDetailId());
        allowDetail.setProcessDetailStatus(allowVO.getProcessDetailStatus());
        if (!isNullOrEmpty(allowVO.getProcessDetailRemark())) {
            allowDetail.setProcessDetailRemark(allowVO.getProcessDetailRemark());
        }

        Date nowDate = new Date();
        allowDetail.setEndTime(nowDate);
        allowDetail.setAllowUserId(user_id);
        if (processDetail.getProcessDetailIsSign() == ASSET_BOOLEAN_TRUE) {
            if (isNullOrEmpty(allowVO.getProcessDetailSign())) {
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
            allowDetail.setProcessDetailSign(allowVO.getProcessDetailSign());
        }
        if (processDetail.getProcessDetailIsStamp() == ASSET_BOOLEAN_TRUE) {
            if (isNullOrEmpty(allowVO.getProcessDetailStamp())) {
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
            allowDetail.setProcessDetailStamp(allowVO.getProcessDetailStamp());
        }
        smsAssetFixedReturnApplyProcessDetailMapper.updateById(allowDetail);

        boolean is_done = false;

        //判断是否最后一个节点 是否驳回
        Integer detailCount = smsAssetFixedReturnApplyProcessDetailMapper.selectCount(new QueryWrapper<SmsAssetFixedReturnApplyProcessDetail>()
                .lambda()
                .eq(SmsAssetFixedReturnApplyProcessDetail::getApplyId, allowVO.getApplyId()));
        if (detailCount.equals(processDetail.getProcessDetailSort()) || allowVO.getProcessDetailStatus() == ASSET_RETURN_ALLOW_STATUS_DENY) {
            is_done = true;

            SmsAssetFixedReturnApply updateApply = new SmsAssetFixedReturnApply();
            updateApply.setId(allowVO.getApplyId());
            updateApply.setEndTime(nowDate);
            updateApply.setAllowStatus(allowVO.getProcessDetailStatus());
            smsAssetFixedReturnApplyMapper.updateById(updateApply);
        }

        //流程结束并且同意，从资产库把对应的资产修改对应状态
        Date now_Date = new Date();
        //流程最后一个人审批完成并且审批通过
        if (detailCount.equals(processDetail.getProcessDetailSort()) && allowVO.getProcessDetailStatus() == ASSET_RETURN_ALLOW_STATUS_PASS) {
//
//            QueryWrapper<SmsAssetFixedReturnApplyGoodsDetail> queryWrapper = new QueryWrapper<>();
//            queryWrapper.lambda().eq(SmsAssetFixedReturnApplyGoodsDetail::getApplyId, allowVO.getApplyId());
//            List<SmsAssetFixedReturnApplyGoodsDetail> list1 = smsAssetFixedReturnApplyGoodsDetailMapper.selectList(queryWrapper);
//            if (list1.size() > 0 || !isNullOrEmpty(list1)) {
//                for (SmsAssetFixedReturnApplyGoodsDetail goodsDetail1 : list1) {
//                    QueryWrapper<SmsAssetMyAssets> queryWrapper1 = new QueryWrapper<>();
//                    queryWrapper1.lambda()
//                            .eq(SmsAssetMyAssets::getAssetId, goodsDetail1.getAssetId())
//                            .eq(SmsAssetMyAssets::getAssetStatus, ASSET_STATUS_BORROW);
//                    List<SmsAssetMyAssets> list2 = smsAssetMyAssetsMapper.selectList(queryWrapper1);
//                    if (list2.size() > 0 || !isNullOrEmpty(list2)) {
//                        for (SmsAssetMyAssets myAssets : list2) {
//                            SmsAssetMyAssets smsAssetMyAssets = new SmsAssetMyAssets();
//                            smsAssetMyAssets.setAssetId(myAssets.getAssetId());
//                            smsAssetMyAssets.setId(myAssets.getId());
//                            smsAssetMyAssetsMapper.deleteById(smsAssetMyAssets.getId());
//                        }
//                    }
//                }
//
//            }
//
//
//            List<SmsAssetFixedReturnApplyGoods> goodsList =
//                    smsAssetFixedReturnApplyGoodsMapper.selectList(new QueryWrapper<SmsAssetFixedReturnApplyGoods>()
//                            .lambda()
//                            .eq(SmsAssetFixedReturnApplyGoods::getApplyId, allowVO.getApplyId()));
//            if (goodsList != null && goodsList.size() > 0) {
//                for (SmsAssetFixedReturnApplyGoods goods : goodsList) {
//                    Integer count = smsAssetFixedStorageMapper.selectCount(new QueryWrapper<SmsAssetFixedStorage>()
//                            .lambda()
//                            .eq(SmsAssetFixedStorage::getAssetName, goods.getAssetName())
//                            .eq(SmsAssetFixedStorage::getAssetCategory, goods.getAssetCategory())
//                            .eq(SmsAssetFixedStorage::getAssetBrand, goods.getAssetBrand())
//                            .eq(SmsAssetFixedStorage::getAssetModel, goods.getAssetModel())
//                            .eq(SmsAssetFixedStorage::getAssetPrice, goods.getAssetPrice())
//                            .eq(SmsAssetFixedStorage::getAssetStatus, ASSET_STATUS_BORROW));
//                    if (count >= goods.getAssetNum()) {
//                        Page<SmsAssetFixedStorage> page = new Page<>(1, goods.getAssetNum());
//                        smsAssetFixedStorageMapper.selectPage(page, new QueryWrapper<SmsAssetFixedStorage>()
//                                .lambda()
//                                .eq(SmsAssetFixedStorage::getAssetStatus, ASSET_STATUS_BORROW)
//                                .eq(SmsAssetFixedStorage::getAssetName, goods.getAssetName())
//                                .eq(SmsAssetFixedStorage::getAssetCategory, goods.getAssetCategory())
//                                .eq(SmsAssetFixedStorage::getAssetBrand, goods.getAssetBrand())
//                                .eq(SmsAssetFixedStorage::getAssetModel, goods.getAssetModel())
//                                .eq(SmsAssetFixedStorage::getAssetPrice, goods.getAssetPrice()));
//                        List<SmsAssetFixedStorage> list = page.getRecords();
//                        for (SmsAssetFixedStorage storage : list) {
//                            SmsAssetFixedReturnApplyGoodsDetail goodsDetail = new SmsAssetFixedReturnApplyGoodsDetail();
//                            goodsDetail.setAssetGoodsId(goods.getId());
//                            goodsDetail.setAssetId(storage.getId());
//                            goodsDetail.setApplyId(allowVO.getApplyId());
//                            smsAssetFixedReturnApplyGoodsDetailMapper.insert(goodsDetail);
//                            storage.setAssetStatus(ASSET_STATUS_IN_STORAGE);
//                            smsAssetFixedStorageMapper.updateById(storage);
//
////                            QueryWrapper<SmsAssetMyAssets> queryWrapper = new QueryWrapper<>();
////                            queryWrapper.lambda().eq(SmsAssetMyAssets::getAssetId,storage.getId());
////                            SmsAssetMyAssets smsAssetMyAssets = smsAssetMyAssetsMapper.selectOne(queryWrapper);
////                            if(!isNullOrEmpty(smsAssetMyAssets)){
////                                SmsAssetMyAssets smsAssetMyAssets1 = new SmsAssetMyAssets();
////                                smsAssetMyAssets1.setAssetId(storage.getId());
////                                smsAssetMyAssetsMapper.deleteById(smsAssetMyAssets1);
////                            }
//
//                        }
//
//
//                    } else {
//                        ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.ASSET_RETURN_ASSET_ERROR));
//                    }
//                }
//
//            }

            //获取资产列表，并判断资产当前状态
            List<SmsAssetFixedReturnApplyGoodsDetail> goodsDetailList = smsAssetFixedReturnApplyGoodsDetailMapper.selectList(new LambdaQueryWrapper<SmsAssetFixedReturnApplyGoodsDetail>()
                    .eq(SmsAssetFixedReturnApplyGoodsDetail::getApplyId,allowVO.getApplyId()));
            if (goodsDetailList == null || goodsDetailList.size() < 1) {
                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.FAIL));
            }
            for (SmsAssetFixedReturnApplyGoodsDetail goodsDetail: goodsDetailList) {
                //判断在库资产状态
                SmsAssetFixedStorage fixedStorage = smsAssetFixedStorageMapper.selectById(goodsDetail.getAssetId());
                if (fixedStorage.getAssetStatus() != com.xyht.sca_s.student_manage_system.modules.assetFixedBorrow.constant.AssetStatusConstant.ASSET_STATUS_BORROW){
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.ASSET_RETURN_STORAGE_NOT_BORROW));
                }
                //判断我的资产状态
                SmsAssetMyAssets myAssets = smsAssetMyAssetsMapper.selectById(goodsDetail.getMyAssetId());
                if (myAssets == null || myAssets.getMyAssetStatus() != MY_ASSET_STATUS_BORROW){
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.ASSET_RETURN_STORAGE_NOT_BORROW));
                }

                //修改我的资产  修改资产在库状态
                SmsAssetMyAssets updateMyAssets = new SmsAssetMyAssets();
                updateMyAssets.setId(myAssets.getId());
                updateMyAssets.setMyAssetStatus(MY_ASSET_STATUS_RETURN);
                updateMyAssets.setReturnTime(new Date());
                smsAssetMyAssetsMapper.updateById(updateMyAssets);

                SmsAssetFixedStorage updateFixedStorage = new SmsAssetFixedStorage();
                updateFixedStorage.setId(goodsDetail.getAssetId());
                updateFixedStorage.setAssetStatus(ASSET_STATUS_IN_STORAGE);
                updateFixedStorage.setAssetOwner("");
                smsAssetFixedStorageMapper.updateById(updateFixedStorage);
            }

        }
        //节点驳回 重置其余节点状态
        if (allowVO.getProcessDetailStatus() == ASSET_RETURN_ALLOW_STATUS_DENY) {
            SmsAssetFixedReturnApplyProcessDetail updateDenyDetail =
                    new SmsAssetFixedReturnApplyProcessDetail();
            updateDenyDetail.setProcessDetailStatus(ASSET_RETURN_ALLOW_STATUS_DENY_FINISH);
            smsAssetFixedReturnApplyProcessDetailMapper.update(updateDenyDetail, new QueryWrapper<SmsAssetFixedReturnApplyProcessDetail>()
                    .lambda()
                    .eq(SmsAssetFixedReturnApplyProcessDetail::getApplyId, allowVO.getApplyId())
                    .eq(SmsAssetFixedReturnApplyProcessDetail::getProcessDetailStatus, ASSET_RETURN_ALLOW_STATUS_WAIT_ALLOW));
        }

        //消息通知
        if (is_done) {
            boolean result_status = false;
            if (allowVO.getProcessDetailStatus() == ASSET_RETURN_ALLOW_STATUS_PASS) {
                result_status = true;
            }
            newTipsUtil.allowFinishTips(allowVO.getApplyId(), user_id, result_status);
        } else {
            SmsAssetFixedReturnApplyProcessDetail nextDetail =
                    smsAssetFixedReturnApplyProcessDetailMapper.selectOne(new QueryWrapper<SmsAssetFixedReturnApplyProcessDetail>()
                            .lambda()
                            .eq(SmsAssetFixedReturnApplyProcessDetail::getApplyId, allowVO.getApplyId())
                            .eq(SmsAssetFixedReturnApplyProcessDetail::getProcessDetailSort, processDetail.getProcessDetailSort() + 1));
            RangeTypeEnum rangeTypeEnum = RangeTypeEnum.RANGE_TYPE_ENUM_PERSON;
            if (nextDetail.getProcessDetailObjectType() == ASSET_RETURN_OBJECT_TYPE_ROLE) {
                rangeTypeEnum = RangeTypeEnum.RANGE_TYPE_ENUM_ROLE;
            }
            List<String> rangeIDList = new ArrayList<>();
            rangeIDList.add(nextDetail.getProcessDetailObjectId());
            newTipsUtil.allowContinueTips(allowVO.getApplyId(),
                    user_id,
                    rangeTypeEnum,
                    rangeIDList,
                    nextDetail.getId());
        }
        return CommonResult.success();
    }

    @Override
    public ResponseResult selectAssetFixedReturnByUserId(Integer PageSize, Integer pageNum, String user_id) {
        if (isNullOrEmpty(user_id)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        QueryWrapper<SmsAssetMyAssets> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(SmsAssetMyAssets::getUserId, user_id)
                .eq(SmsAssetMyAssets::getMyAssetStatus, MY_ASSET_STATUS_BORROW);
        Page<SmsAssetMyAssets> page = new Page<>(pageNum, PageSize);
        smsAssetMyAssetsMapper.selectPage(page, queryWrapper);
        List<SmsAssetMyAssets> list1 = page.getRecords();
        List<SmsAssetMyAssetsDTO> list = new ArrayList<>();
        if (isNullOrEmpty(list1)) {
            return CommonResult.success(list, 0);
        }

        for (SmsAssetMyAssets myAssets : list1) {
            QueryWrapper<SmsAssetFixedStorage> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.lambda().eq(SmsAssetFixedStorage::getId, myAssets.getAssetId())
            ;
            SmsAssetFixedStorage smsAssetFixedStorage = smsAssetFixedStorageMapper.selectOne(queryWrapper1);
            if (!isNullOrEmpty(smsAssetFixedStorage)) {
                QueryWrapper<SmsAssetCategoryManagement> queryWrapper2 = new QueryWrapper<>();
                queryWrapper2.lambda().eq(SmsAssetCategoryManagement::getId, smsAssetFixedStorage.getAssetCategory());
                SmsAssetCategoryManagement query = smsAssetCategoryManagementMapper.selectOne(queryWrapper2);
                if (isNullOrEmpty(query)) {
                    return CommonResult.failed(CommonCodeEnum.ASSET_RETURN_CATEGORY_NOT_EXIST);
                }
                SmsAssetMyAssetsDTO smsAssetMyAssetsDTO = new SmsAssetMyAssetsDTO();
                BeanUtils.copyProperties(smsAssetFixedStorage, smsAssetMyAssetsDTO);
                smsAssetMyAssetsDTO.setAssetCategory(query.getCategoryName());
                smsAssetMyAssetsDTO.setCateGoryId(query.getId());
                list.add(smsAssetMyAssetsDTO);
            }
        }
        int total = (int) page.getTotal();
        return CommonResult.success(list, total);
    }

    @Override
    public ResponseResult selectAll(String apply_person, String apply_department, Integer pageSize, Integer pageNum) {
        List<SmsAssetFixedReturnApply> list11 = new ArrayList<>();
        QueryWrapper<SmsAssetFixedReturnApply> queryWrapper = new QueryWrapper<>();
        if (isNullOrEmpty(queryWrapper)) {
            return CommonResult.failed(CommonCodeEnum.DATA_NOT_FOUND);
        }

        if (!isNullOrEmpty(apply_person)) {
            queryWrapper.lambda().like(SmsAssetFixedReturnApply::getApplyPerson, apply_person);
        }
        if (!isNullOrEmpty(apply_department)) {
            queryWrapper.lambda().like(SmsAssetFixedReturnApply::getApplyDepartment, apply_department);
        }

        List<SmsAssetFixedReturnApply> list1 = smsAssetFixedReturnApplyMapper.selectList(queryWrapper);
        if (list1.size() == 0) {
            return CommonResult.success(list11, 0);
        }
        queryWrapper.orderByDesc("create_time");
        Page<SmsAssetFixedReturnApply> page = new Page<>(pageNum, pageSize);
        smsAssetFixedReturnApplyMapper.selectPage(page, queryWrapper);
        list11 = page.getRecords();
        int total = (int) page.getTotal();
        return CommonResult.success(list11, total);
    }

    @Override
    @Async
    public Future<ResponseResult> exportFixedReturnApplication(SmsAssetFixedReturnApplyExportVO exportVO, HttpServletResponse response) {
        if (isNullOrEmpty(exportVO.getIsExportProcess())) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }
        try {
            QueryWrapper<SmsAssetFixedReturnApply> queryWrapper = new QueryWrapper<>();

            if (!isNullOrEmpty(exportVO.getApplyDepartment())) {
                queryWrapper.lambda().like(SmsAssetFixedReturnApply::getApplyDepartment, exportVO.getApplyDepartment());
            }
            if (!isNullOrEmpty(exportVO.getApplyPerson())) {
                queryWrapper.lambda().like(SmsAssetFixedReturnApply::getApplyPerson, exportVO.getApplyPerson());
            }
            queryWrapper.lambda().orderByDesc(SmsAssetFixedReturnApply::getCreateTime);
            List<SmsAssetFixedReturnApply> list = smsAssetFixedReturnApplyMapper.selectList(queryWrapper);
            //表头数据
            String[] header = exportVO.getLimitColumn().toArray(new String[0]);
            double sheetNum;
            //声明一个工作簿
            HSSFWorkbook workbook = new HSSFWorkbook();
            if (list != null && list.size() > 0) {
                sheetNum = Math.ceil((double) list.size() / PER_SHEET_NUM);
                for (int k = 0; k < sheetNum; k++) {
                    //生成一个表格，设置表格名称为"资源导出表"
                    HSSFSheet sheet = workbook.createSheet("固定资产归还申请记录导出表" + (k + 1));

                    //设置表格列宽度为10个字节
                    sheet.setDefaultColumnWidth(12);
                    //创建标题的显示样式
                    HSSFCellStyle headerStyle = workbook.createCellStyle();
                    headerStyle.setFillForegroundColor(IndexedColors.YELLOW.index);
                    headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

                    HSSFFont f = workbook.createFont();
                    f.setFontHeightInPoints((short) 10);//字号
                    f.setBold(true);//加粗
                    headerStyle.setFont(f);
                    //创建第一行表头
                    HSSFRow headrow = sheet.createRow(0);

                    //遍历添加表头(下面模拟遍历学生，也是同样的操作过程)
                    for (int i = 0; i < header.length + 1; i++) {
                        //创建一个单元格
                        HSSFCell cell = headrow.createCell(i);

                        if (i == 0) {
                            //创建一个内容对象
                            HSSFRichTextString text = new HSSFRichTextString("序号");
                            //将内容对象的文字内容写入到单元格中
                            cell.setCellValue(text);
                            cell.setCellStyle(headerStyle);
                            continue;
                        }
                        //创建一个内容对象
                        String header1 = apiModelUtil.getFieldValueByFieldName(SmsAssetFixedReturnApply.class, header[i - 1]);
                        HSSFRichTextString text = new HSSFRichTextString(header1);

                        //将内容对象的文字内容写入到单元格中
                        cell.setCellValue(text);
                        cell.setCellStyle(headerStyle);
                    }

                    //判断是否需要添加流程表头
                    if (exportVO.getIsExportProcess() == EXPORT_PROCESS_TRUE) {
                        List<SmsAssetFixedReturnApplyProcessDetail> processList =
                                smsAssetFixedReturnApplyProcessDetailMapper.selectList(new QueryWrapper<>());
                        if (processList != null && processList.size() > 0) {
                            Integer origin_num = header.length + 1;
                            for (SmsAssetFixedReturnApplyProcessDetail process : processList) {
                                String process_name = process.getProcessDetailName();
                                addProcessTableHead(headrow, headerStyle, origin_num, process_name);
                                origin_num += 4;
                            }
                        }
                    }

                    int range = PER_SHEET_NUM;
                    if (k + 1 == sheetNum) {
                        range = list.size() - (PER_SHEET_NUM) * k;
                    }
                    for (int i = 0; i < range; i++) {
                        //创建一行
                        HSSFRow row1 = sheet.createRow(i + 1);
                        SmsAssetFixedReturnApply returnApply = list.get((PER_SHEET_NUM) * k + i);
                        Map map = JSONObject.parseObject(JSON.toJSONString(returnApply), Map.class);
                        row1.createCell(0).setCellValue(new HSSFRichTextString(i + 1 + ""));
                        for (int j = 0; j < header.length; j++) {
                            String rowContent = "";
                            if (map.get(header[j]) instanceof Long) {
                                rowContent = TimeUtil.DateformatTimestamp((long) map.get(header[j]));
                            } else {
                                if (header[j].equals("applyUserId")) {
                                    SmsUser smsUser = cacheUtil.getUserInfo(returnApply.getApplyUserId());
                                    if (smsUser != null) {
                                        rowContent = smsUser.getRealName();
                                    } else {
                                        rowContent = "";
                                    }
                                } else {
                                    rowContent = (String) map.get(header[j]);
                                }
                            }
                            row1.createCell(j + 1).setCellValue(new HSSFRichTextString(rowContent));
                        }

                        if (exportVO.getIsExportProcess() == EXPORT_PROCESS_TRUE) {
                            List<SmsAssetProcessDetail> processList =
                                    smsAssetProcessDetailMapper.selectList(new QueryWrapper<>());
                            if (processList != null && processList.size() > 0) {
                                Integer origin_num = header.length + 1;
                                for (SmsAssetProcessDetail process : processList) {
                                    SmsAssetFixedReturnApplyProcessDetail detail =
                                            smsAssetFixedReturnApplyProcessDetailMapper.selectOne(new QueryWrapper<SmsAssetFixedReturnApplyProcessDetail>()
                                                    .lambda()
                                                    .eq(SmsAssetFixedReturnApplyProcessDetail::getApplyId, returnApply.getId())
                                                    .eq(SmsAssetFixedReturnApplyProcessDetail::getProcessDetailId, process.getId())
                                            );
                                    if (detail == null || detail.getId() == null) {
                                        origin_num += 4;
                                    } else {
                                        //审批人
                                        SmsUser user = cacheUtil.getUserInfo(detail.getAllowUserId());
                                        if (user == null) {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString(""));
                                        } else {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString(user.getRealName()));
                                        }

                                        //审批时间
                                        Date allow_time = detail.getEndTime();
                                        if (allow_time == null) {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString(""));
                                        } else {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString(TimeUtil.DateHanZiSimpleFormat(allow_time)));
                                        }

                                        //审批状态
                                        Integer allow_status = detail.getProcessDetailStatus();
                                        if (allow_status == EXAMINE_STATUS_PASS) {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString("同意"));
                                        } else if (allow_status == EXAMINE_STATUS_DENY) {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString("拒绝"));
                                        } else {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString(""));
                                        }

                                        //审批意见
                                        String allow_option = detail.getProcessDetailRemark();
                                        if (isNullOrEmpty(allow_option)) {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString(""));
                                        } else {
                                            row1.createCell(origin_num++).setCellValue(new HSSFRichTextString(allow_option));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

//            response.reset();
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("固定资产归还记录导出表.xlsx", "utf-8"));
            response.setCharacterEncoding("utf-8");
            response.setHeader("file-type", "download");
            response.setHeader("file-name", URLEncoder.encode("固定资产归还记录导出表.xlsx", "utf-8"));
            response.setHeader("Access-Control-Expose-Headers", "file-type,file-name");
//            //刷新缓冲
            response.flushBuffer();
            //workbook将Excel写入到response的输出流中，供页面下载
            OutputStream os = response.getOutputStream();
            workbook.write(os);

            workbook.close();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.FAIL));
        }
        return null;
    }

    private void addProcessTableHead(HSSFRow headRow, HSSFCellStyle headerStyle, Integer origin_cell_num, String originHeadContent) {
        Integer cell_num = origin_cell_num;

        setTableHead(headRow, headerStyle, cell_num++, originHeadContent + "审批人");
        setTableHead(headRow, headerStyle, cell_num++, originHeadContent + "审批时间");
        setTableHead(headRow, headerStyle, cell_num++, originHeadContent + "审批状态");
        setTableHead(headRow, headerStyle, cell_num, originHeadContent + "审批意见");

    }

    private void setTableHead(HSSFRow headRow, HSSFCellStyle headerStyle, Integer cell_num, String headContent) {
        HSSFCell cell = headRow.createCell(cell_num);
        //创建一个内容对象
        HSSFRichTextString text = new HSSFRichTextString(headContent);

        //将内容对象的文字内容写入到单元格中
        cell.setCellValue(text);
        cell.setCellStyle(headerStyle);
    }
}
